﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace HuntWump2
{
    class Cave
    {
        public static List<Room> rooms = new List<Room>();
        private Random rand = new Random();
        private static readonly int numPossibleDoorDirections = 6;

        public Cave()
        {
            makeRooms();
            makeDoorsRecursive(rand.Next(30));
            for (int i = 0; i < rooms.Count; i++)
            {
                if (rooms[i].getNumDoors() == 0)
                    makeDoorsRecursive(i);
            }
        }


        private void makeRooms()
        {
            for (int i = 0; i <= 29; i++)
            {
                rooms.Add(new Room(i));
            }
        }

        private void makeDoorsRecursive(int roomNumber)
        {
            // Creating a biased integer from 1 to 3, leaning slightly more towards 3
            int[] maxDoorOptions = { 1, 1, 1, 2, 2, 2, 3, 3, 3, 3 };
            int maxDoors = maxDoorOptions[rand.Next(maxDoorOptions.Length)];


            bool doorAdded = true;
            while (doorAdded && rooms[roomNumber].getNumDoors() < maxDoors)
            {
                doorAdded = false;
                for (int desiredDoorsInPotentialConnection = 0; desiredDoorsInPotentialConnection < 3; desiredDoorsInPotentialConnection++)
                {
                    List<int> potentialRooms = new List<int>();

                    // note: numPossibleDoorDirections is always 6, and is simply used to go around the hexagon and find the rooms numbers
                    for (int doorOption = 0; doorOption < numPossibleDoorDirections; doorOption++)
                    {
                        if (rooms[roomNumber].hasDoor(doorOption) == false &&
                            rooms[getRoomInDirection(roomNumber, doorOption)].getNumDoors() <= desiredDoorsInPotentialConnection)

                            potentialRooms.Add(doorOption);
                    }
                    if (potentialRooms.Count > 0)
                    {
                        int roomsListIndex = rand.Next(potentialRooms.Count);
                        int direction = potentialRooms[roomsListIndex];
                        rooms[roomNumber].addDoor(direction);


                        int d2 = direction - (numPossibleDoorDirections / 2);
                        if (d2 < 0) d2 += numPossibleDoorDirections;
                        int room = getRoomInDirection(roomNumber, direction);
                        rooms[room].addDoor(d2);


                        doorAdded = true;


                        makeDoorsRecursive(room);
                        break;
                    }
                }
            } // end while loop
        }


        public static int getRoomInDirection(int roomNumber, int direction)
        {
            // Code was originally written in base 1 (1-30 and 1-6), but parameters come in base 0 (0-29 and 0-5)
            direction += 1;

            int roomInDirection = roomNumber;
            if (direction == 1) roomInDirection -= 6;
            else if (direction == 2)
            {
                if (roomNumber % 2 == 0 && roomNumber != 6 && roomNumber != 12 && roomNumber != 18 && roomNumber != 24 && roomNumber != 0) roomInDirection += 1;
                else roomInDirection -= 5;
            }
            else if (direction == 3)
            {
                if (roomNumber % 2 != 0 || roomNumber == 6 || roomNumber == 12 || roomNumber == 18 || roomNumber == 24 || roomNumber == 0) roomInDirection += 1;
                else roomInDirection += 7;
            }
            else if (direction == 4) roomInDirection += 6;
            else if (direction == 5)
            {
                if (roomNumber % 2 != 0 && roomNumber != 1 && roomNumber != 7 && roomNumber != 13 && roomNumber != 19 && roomNumber != 25) roomInDirection -= 1;
                else roomInDirection += 5;
            }
            else if (direction == 6)
            {
                if (roomNumber % 2 == 0 || roomNumber == 1 || roomNumber == 7 || roomNumber == 13 || roomNumber == 19 || roomNumber == 25) roomInDirection -= 1;
                else roomInDirection -= 7;
            }

            // make valid room number
            if (roomInDirection > 29) roomInDirection -= 30;
            if (roomInDirection < 0) roomInDirection += 30;

            // return to base 0 room number (0-29)

            return roomInDirection;
        }

        public static int[] connectedRooms(int roomNumber)
        {
            int[] connectedRms = new int[rooms[roomNumber].getDoors().Count];
            for (int i = 0; i < connectedRms.Length; i++)
            {
                connectedRms[i] = getRoomInDirection(roomNumber, rooms[roomNumber].getDoors()[i]);
            }
            return connectedRms;
        }

        public static int[] connectedRoomsDirection(int roomNumber)
        // this method will return an array of numbers that gives the direction of the rooms
        // the numbers go from 0 to 5, 0 being the top center and then each consecutive number moving clockwise around the hexagon
        {
            int[] connectedRms = rooms[roomNumber].getDoors().ToArray();
            return connectedRms;
        }
    }
}
